from pypinyin import lazy_pinyin
from enum import Enum
from typing import List
import os
import re


class CharKind(Enum):
    '字符类型'
    U_C_LETTER = 1
    '大写字母'
    L_C_LETTER = 2
    '小写字母'
    CHINESE = 3
    '汉字'
    NUMBER = 4
    '数字'
    OTHER = 5
    '其它'


class Common():
    def __init__(self, data: str = '', parentMenu=None, notes: List[str] = []):
        self.data: str = data
        self.name: str = ''
        '名字'
        self.wordsOfName: List[str] = []
        '名字的单词'
        self.parentMenu = parentMenu
        '父菜单'
        self.numToSameName = -1
        '用于区分同名的数字'
        self._notes: List[str] = notes
        '注释'

    def _printList(self, list, maxLogNum=100):
        c = 0
        for n in list:
            print(n)
            c += 1
            if c > maxLogNum:
                break
        if c > maxLogNum:
            print('...')

    def _isUpperCaseLetters(self, c) -> bool:
        '是大写字母'
        return 'A' <= c <= 'Z'

    def _isLowerCaseLetters(self, c) -> bool:
        '是小写字母'
        return 'a' <= c <= 'z'

    def _isLetters(self, c) -> bool:
        '是字母'
        return self._isUpperCaseLetters(c) or self._isLowerCaseLetters(c)

    def _isLetterKind(self, kind) -> bool:
        '是字母类型'
        return kind == CharKind.U_C_LETTER or kind == CharKind.L_C_LETTER

    def _isChinese(self, c) -> bool:
        '是汉字'
        return '\u4e00' <= c <= '\u9fff'

    def _isNumber(self, c) -> bool:
        '是数字'
        return '0' <= c <= '9'

    def _calCharKind(self, c) -> CharKind:
        '计算字符类型'
        if self._isUpperCaseLetters(c):
            return CharKind.U_C_LETTER
        elif self._isLowerCaseLetters(c):
            return CharKind.L_C_LETTER
        elif self._isChinese(c):
            return CharKind.CHINESE
        elif self._isNumber(c):
            return CharKind.NUMBER
        else:
            return CharKind.OTHER

    def _parseNameWords(self, name) -> List[str]:
        '解析出名字的每个单词'
        words = []
        word = ''
        lastCharKind = None
        for i in range(len(name)):
            curKind = self._calCharKind(name[i])

            # 汉字
            if curKind == CharKind.CHINESE:
                # 上个是字母类型说明前面有个单词
                if self._isLetterKind(lastCharKind):
                    words.append(word.lower())

                words.append(lazy_pinyin(name[i])[0])
                word = ''
            # 大写字母
            elif curKind == CharKind.U_C_LETTER:
                # 上个是字母类型说明前面有个单词
                if self._isLetterKind(lastCharKind):
                    words.append(word.lower())
                word = name[i]
            # 小写字母
            elif curKind == CharKind.L_C_LETTER:
                if self._isLetterKind(lastCharKind):
                    word += name[i]
                # 前面是汉字或其它
                else:
                    word = name[i]
            elif curKind == CharKind.NUMBER:
                # 上个是字母类型说明前面有个单词
                if self._isLetterKind(lastCharKind):
                    words.append(word.lower())

                words.append(name[i])
                word = ''
            # 其它
            else:
                if self._isLetterKind(lastCharKind):
                    words.append(word.lower())

            lastCharKind = curKind

        # 处理最后一个单词
        if self._isLetterKind(lastCharKind):
            words.append(word.lower())

        return words

    def _getNamePath(self) -> str:
        if self.parentMenu == None:
            return ''
        else:
            return self.parentMenu._getPath() + '/' + self.name

    def _handleEnvironOfPath(self, path: str) -> str:
        '处理路径中的环境变量'
        ret = re.match('^%(.*)%', path)
        if ret == None:
            return path
        else:
            return os.environ[ret.group(1)] + path[ret.group(0).__len__():]

    def isOneWord(self) -> bool:
        '项名为一个字'
        return self.wordsOfName.__len__() == 1

    def getHotkeyPathLen(self) -> int:
        '快捷键路径长度'
        if self.isOneWord():
            return self.wordsOfName[0].__len__()
        else:
            return self.wordsOfName.__len__()

    def getHotkey(self, n: int) -> str:
        '获得对应位置的快捷键'
        assert n < self.getHotkeyPathLen(), '超过快捷键路径长度'

        if self.isOneWord():
            return self.wordsOfName[0][n]
        else:
            return self.wordsOfName[n][0]

    def _getNotesIni(self) -> str:
        if self._notes.__len__() == 0:
            return ''
        
        level = self.parentMenu.level + 1
        ret = ''
        for note in self._notes:
            ret += '%s%s\n' % ('\t'*(level-1), note)
        return ret